/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.audit.management;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.koron.audit.approval.AfterApprovalService;
import com.koron.audit.domain.Audit;
import com.koron.audit.mapper.AuditMapper;
import com.koron.audit.service.api.AuditService;
import com.koron.audit.service.api.WorkFlowAuxiliaryService;
import com.koron.common.bean.DeptBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.emailandsms.SendEmail;
import com.koron.common.emailandsms.SendMsg;
import com.koron.common.web.Util;
import com.koron.workflow.service.api.WorkflowService;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.swan.bean.MessageBean;

import java.util.*;

@PropertySource(value = {"classpath:application.properties"})
@Service
public class FlowManagement {

    private final static  Logger logger = LoggerFactory.getLogger(FlowManagement.class);

    @Autowired
    private WorkflowService flowService;

    @Autowired
    private Util util;

    @Autowired
    private AuditService auditService;

    @Autowired
    private WorkFlowAuxiliaryService wfaService;

    Map<String, Object> handlers = new HashMap<String, Object>();

//    @Value("${wx.domain.name}")
//    private String domainName;

    /**
     * 启动业务流程，包括生成工作流程的数据记录等
     *
     * @param user
     * @param audit
     * @param parameterMap
     * @return
     */
    @SuppressWarnings("deprecation")
    public boolean initFlow(StaffBean user, Audit audit, Map<String, Object> parameterMap) {
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            AuditMapper mapper = factory.getMapper(AuditMapper.class);
            audit.setCode(audit.getId());
            mapper.insert(audit);
//            Map<String, Object> businessData = new HashMap<>();
//            if (!parameterMap.isEmpty()) {
//                businessData.putAll(parameterMap);
//            }
            MessageBean<?> messageBean = flowService.start(audit.getSetCode(), audit.getTemplateKey(), audit.getId(), user.getUserid(), audit.getTitle(), audit.getDescription(), JSON.toJSONString(parameterMap), audit.getNextParticipantCode(), audit.getAttachment());
//            businessData.put("leaderCode", user.getCode());
//            MessageBean<?> messageBean = flowService.startUpFlow(audit.getTemplateKey(), audit.getFlowName(), "", user.getCode(),audit.getId(), businessData);
            if (messageBean.getCode() == 0) {
                Map map = (Map) messageBean.getData();
                // 获取下个节点审批人信息
                List<Map> tasks = (List<Map>) map.get("tasks");
                String instanceId = (String) map.get("processInstanceId");
                audit.setFlowInstanceId(instanceId);
                audit.setCode("WF" + instanceId);
                mapper.update(audit);
                factory.close(true);
                return true;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        if (factory != null) {
            factory.close(false);
        }
        return false;
    }


    //发邮件
    public void sendEmail(String processinsId) {
        try {
            Audit audit = auditService.queryByProcessId(processinsId);
            if (audit == null) {
                return;
            }
            String grabHistory = flowService.grabHistory(audit.getFlowInstanceId());
            Map map = new Gson().fromJson(grabHistory, Map.class);
            if (map.get("data") != null) {
                List<Map> list = (List<Map>) map.get("data");
                if (!list.isEmpty()) {
                    map = list.get(0);
                    String nextcandidateUsers = (String) map.get("nextcandidateUsers");
                    if (StringUtils.isEmpty(nextcandidateUsers)) {
                        return;
                    }
                    String[] userArray = nextcandidateUsers.split("[,，]");
                    if (userArray.length == 0) {
                        return;
                    }
                    for (String userCode : userArray) {
                        if (userCode.startsWith("1-")) {
                            userCode = userCode.substring(2);
                        }
                        //通过code查询用户对象
                        MessageBean<?> msg = util.staff(userCode, 0);
                        List<String> toUser = new ArrayList<String>();
                        if (msg.getCode() == 0) {
                            List<StaffBean> userList = (List<StaffBean>) msg.getData();
                            if (!userList.isEmpty()) {
                                StaffBean staff = userList.get(0);
                                if (staff != null) {
                                    if (!StringUtils.isEmpty(staff.getEmail())) {
                                        toUser.add(staff.getEmail());
                                    }
                                }
                            }
                        }
                        if (!toUser.isEmpty()) {
                            SendEmail.complexMailSend(toUser, "您有新的待审单据", "安全管理信息系统", "http://safety.gdhwater.com/web/index.html", null);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    ;

    //发短信
    public void sendShortMsg(String processinsId) {
        try {
            Audit audit = auditService.queryByProcessId(processinsId);
            if (audit == null) {
                return;
            }
            String grabHistory = flowService.grabHistory(audit.getFlowInstanceId());
            Map map = new Gson().fromJson(grabHistory, Map.class);
            if (map.get("data") != null) {
                List<Map> list = (List<Map>) map.get("data");
                if (!list.isEmpty()) {
                    map = list.get(0);
                    String nextcandidateUsers = (String) map.get("nextcandidateUsers");
                    if (StringUtils.isEmpty(nextcandidateUsers)) {
                        return;
                    }
                    String[] userArray = nextcandidateUsers.split("[,，]");
                    if (userArray.length == 0) {
                        return;
                    }
                    for (String userCode : userArray) {
                        if (userCode.startsWith("1-")) {
                            userCode = userCode.substring(2);
                        }
                        //通过code查询用户对象
                        MessageBean<?> msg = util.staff(userCode, 0);
                        if (msg.getCode() == 0) {
                            List<StaffBean> userList = (List<StaffBean>) msg.getData();
                            if (!userList.isEmpty()) {
                                StaffBean staff = userList.get(0);
                                if (staff != null) {
                                    if (!StringUtils.isEmpty(staff.getMobile())) {
                                        SendMsg.sendSMS(staff.getMobile(), "您在安全管理信息系统有一条待审单据。");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    ;

    public void setTodoDone(String userId, String processinsId) {
        try {
            Audit audit = auditService.queryByProcessId(processinsId);
            if (audit == null) {
                return;
            }
            if (StringUtils.isEmpty(userId)) {
                return;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    public void sendToDo(String processinsId) {
        try {
            Audit audit = auditService.queryByProcessId(processinsId);
            if (audit == null) {
                return;
            }
            String grabHistory = flowService.grabHistory(audit.getFlowInstanceId());
            Map map = new Gson().fromJson(grabHistory, Map.class);
            if (map.get("data") != null) {
                List<Map> list = (List<Map>) map.get("data");
                if (!list.isEmpty()) {
                    map = list.get(0);
                    String nextcandidateUsers = (String) map.get("nextcandidateUsers");
                    if (StringUtils.isEmpty(nextcandidateUsers)) {
                        return;
                    }
                    String[] userArray = nextcandidateUsers.split(",");
                    if (userArray.length == 0) {
                        return;
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    /**
     * 审批通过执行的业务处理
     *
     * @param auditId
     */
    public void afterApprove(String auditId, ApplicationContext ctx) {
        Audit audit = auditService.queryOne(auditId);
        if (audit == null) {
            return;
        }
        audit.setState(2); //审批通过
        auditService.update(audit);
        if (handlers.get(audit.getTarget()) != null) {
            AfterApprovalService afterApprovalService = (AfterApprovalService) handlers.get(audit.getTarget());
            Integer operation = audit.getOperation();
            audit.setCtx(ctx);
            if (1 == operation) {
                afterApprovalService.editApproval(audit);
            }
            if (2 == operation) {
                afterApprovalService.discardApproval(audit);
            }
        }

    }

    public Map<String, Object> getHandlers() {
        return handlers;
    }

    public void processDiscard(String auditId) {
        Audit audit = auditService.queryOne(auditId);
        if (audit == null) {
            return;
        }
        audit.setState(3); //流程废弃
        auditService.update(audit);
        if (handlers.get(audit.getTarget()) != null) {
            AfterApprovalService afterApprovalService = (AfterApprovalService) handlers.get(audit.getTarget());
            afterApprovalService.processDiscard(audit);
        }

    }

    ;

    @SuppressWarnings({"rawtypes", "unchecked"})
    public String getNextLeaderCode(String processinsId) {
        try {
            Audit audit = auditService.queryByProcessId(processinsId);
            if (audit == null) {
                return null;
            }
            String templateKey = audit.getTemplateKey();
            if (StringUtils.isEmpty(templateKey)) {
                return null;
            }
            String processName = "";
            String grabHistory = flowService.grabHistory(audit.getFlowInstanceId());
            Map map = new Gson().fromJson(grabHistory, Map.class);
            if (map.get("data") != null) {
                List<Map> list = (List<Map>) map.get("data");
                if (!list.isEmpty()) {
                    map = list.get(0);
                    processName = (String) map.get("nextactivitiId");
                    if (StringUtils.isEmpty(processName)) {
                        return null;
                    }
                }
            }
            if (wfaService.count(templateKey, processName) == 0) {
                return null;
            }
            //发起人
            String initiatorCode = audit.getInitiatorCode();
            if (StringUtils.isEmpty(initiatorCode)) {
                return null;
            }
            MessageBean<?> deptMsg = util.dept(initiatorCode);
            if (0 != deptMsg.getCode()) {
                return null;
            }
            List list = (List) deptMsg.getData();
            if (list.isEmpty()) {
                return null;
            }
            DeptBean dept = (DeptBean) list.get(0);
            if (dept == null) {
                return null;
            }
            String keyType = dept.getCode();
            return wfaService.userCode(templateKey, processName, keyType);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 流程审批
     *  @param auditId
     * @param operation      1驳回 2转办 32通过
     * @param rejectNodeCode 驳回节点
     * @param relatedUser
     * @param map
     */
    public void approve(String auditId, Integer operation, String rejectNodeCode, String relatedUser, Map map) {
        Objects.requireNonNull(auditId);
        Objects.requireNonNull(operation);
        Audit audit = auditService.queryOne(auditId);
        audit.setNextParticipantCode(relatedUser);
        if (audit == null) {
            return;
        }
        // 获取节点审批人
        List<Map> tasks = null;
        List<String> userIdList = new ArrayList<>();
        if (map.get("tasks") != null && !StringUtils.isEmpty(map.get("tasks").toString())) {
            tasks = (List<Map>) map.get("tasks");
            if (null != tasks && tasks.size() > 0) {
                Map map1 = tasks.get(0);
                if (null != map1 && !map1.isEmpty()) {
                    String user = (String) map1.get("user");
                    if (!StringUtils.isEmpty(user)) {
                        String[] userArray = user.split("[,，]");
                        if (userArray.length > 0) {
                            for (String userId : userArray) {
                                if (userId.startsWith("1-")) {
                                    userId = userId.substring(2);
                                }
                                userIdList.add(userId);
                            }
                        }
                    }
                }
            }
        }
        if (audit.getOperation() == 1) {
            if (handlers.get(audit.getTarget()) != null) {
                AfterApprovalService afterApprovalService = (AfterApprovalService) handlers.get(audit.getTarget());
                if (operation == 1 && !StringUtils.isEmpty(rejectNodeCode)) {
                    afterApprovalService.reject(audit, userIdList);
                } else if (operation == 2 || operation == 32) {
                    afterApprovalService.passApproval(operation, audit);
                }
            }
        }
    }

}
